package com.tiantian.novel.helper;

import freemarker.template.Configuration;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Locale;

/**
 * Freemarker factory for kindle
 *
 * @author wangkai
 * @since 2020/11/23.
 */
public class KindleFreemarkerHelper {
    private static final Logger log = LoggerFactory.getLogger(KindleFreemarkerHelper.class);
    private static final String DEFAULT_STYLE = "/default/";

    private static final String UTF8 = "utf8";
    /**
     * kindle资源所在目录
     */
    private String kindleHome;
    private String style = DEFAULT_STYLE;
    private Configuration cfg;
    private String ftlHome;

    /**
     * kindle文件存放的目录
     *
     * @param kindleHome
     * @param style
     */
    private KindleFreemarkerHelper(String kindleHome, String style) throws IOException {
        log.info("=====init KindleFreemarkerHelper Configuration=====");
        if (kindleHome != null) {
            this.kindleHome = kindleHome;
        }
        if (style != null) {
            this.style = "/" + style + "/";
        }
        this.ftlHome = kindleHome + this.style;
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_30);
//        configuration.setClassForTemplateLoading(KindleFreemarkerHelper.class, ftlHome);
        configuration.setDirectoryForTemplateLoading(new File(ftlHome));
        configuration.setDefaultEncoding(UTF8);
        configuration.setEncoding(Locale.CHINA, UTF8);
        configuration.setNumberFormat("0.##");
        this.cfg = configuration;

    }

    public static KindleFreemarkerHelper getInstance(String home) throws IOException {
        return new KindleFreemarkerHelper(home, DEFAULT_STYLE);
    }

    /**
     * 指定模板目录
     *
     * @param style
     * @return
     */
    public static KindleFreemarkerHelper getInstance(String home, String style) throws IOException {
        return new KindleFreemarkerHelper(home, style);
    }

    /**
     * 加载指定目录的模板
     *
     * @param ftlName
     * @param style
     * @return
     * @throws Exception
     */
    private Template getTemplate(String ftlName, String style) throws Exception {
        cfg.setClassForTemplateLoading(KindleFreemarkerHelper.class, style);
        return cfg.getTemplate(ftlName);
    }

    /**
     * 生成String
     *
     * @param ftlName
     * @param dataModel
     * @return
     * @throws Exception
     */
    public String toString(String ftlName, Object dataModel) throws Exception {
        Template template = getTemplate(ftlName);
        log.info("loading template '{}'", template.getName());
        StringWriter out = new StringWriter();
        template.process(dataModel, out);
        return out.toString();
    }

    /**
     * 打印到控制台
     *
     * @param ftlName
     * @param dataModel
     * @throws Exception
     */
    public void toConsole(String ftlName, Object dataModel) throws Exception {
        Template template = getTemplate(ftlName);
        log.info("loading template '{}'", template.getName());
        template.process(dataModel, new PrintWriter(System.out));
    }

    /**
     * 输出到文件
     *
     * @param ftlName
     * @param dataModel
     * @param dest
     * @throws Exception
     */
    public void toFile(String ftlName, Object dataModel, File dest) throws Exception {
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        if (!dest.exists()) {
            dest.createNewFile();
        }
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest), UTF8));
        Template template = getTemplate(ftlName);
        log.info("loading template '{}'", template.getName());
        template.process(dataModel, out);
        out.flush();
        out.close();
    }

    private Template getTemplate(String name) throws IOException {
        return cfg.getTemplate(name);
    }

    public String getAbsolutePath(String dir) throws IOException {
        return kindleHome + File.separator + dir;
    }

    public String getExe(String os) throws IOException {
        String basePath = kindleHome + File.separator;
        String file = "kindlegen.exe";
        if ("linux".equals(os)) {
            file = "kindlegen";
        }
        return basePath + "bin/" + file;
    }
}
